home *** CD-ROM | disk | FTP | other *** search
/ Acorn RISC PD-CD 1 / Acorn RISC PD-CD 1.iso / games / _gnuchess / src / c / nuxdsp < prev    next >
Encoding:
Text File  |  1994-02-25  |  40.1 KB  |  1,855 lines

  1. /* nuxdsp.c - (new)  ALPHA interface for CHESS
  2.  
  3.   Revision: 1990-05-09
  4.  
  5.   Copyright (C) 1986, 1987, 1988, 1989, 1990 Free Software Foundation, Inc.
  6.   Copyright (c) 1988, 1989, 1990  John Stanback
  7.  
  8.   Modified extensively Nov 1989 Christopher North-Keys
  9.     40x24 two-colour display
  10.         option for shading black squares
  11.         expanded game save, list, and restore features using $HOME
  12.         option to disable display of coordinates
  13.         optional auto-updating of positional information
  14.         optional starring of black side
  15.         mass toggle for reverse-video functions
  16.  
  17.   This file is part of CHESS.
  18.  
  19.   CHESS is distributed in the hope that it will be useful, but WITHOUT ANY
  20.   WARRANTY.  No author or distributor accepts responsibility to anyone for
  21.   the consequences of using it or for whether it serves any particular
  22.   purpose or works at all, unless he says so in writing.  Refer to the CHESS
  23.   General Public License for full details.
  24.  
  25.   Everyone is granted permission to copy, modify and redistribute CHESS, but
  26.   only under the conditions described in the CHESS General Public License.
  27.   A copy of this license is supposed to have been given to you along with
  28.   CHESS so you can know your rights and responsibilities.  It should be in a
  29.   file named COPYING.  Among other things, the copyright notice and this
  30.   notice must be preserved on all copies.
  31. */
  32.  
  33.  
  34. #include <ctype.h>
  35. #include <signal.h>
  36. #ifdef MSDOS
  37.  #include <dos.h>
  38.  #include <conio.h>
  39.  #include <stdlib.h>
  40.  #include <string.h>
  41.  #include <time.h>
  42.  
  43.  #define ESC 0x1B
  44.  #define scanz scanf
  45.  #define printz printf
  46.  #define refresh() fflush(stdout)
  47.  
  48.  int mycntl1, mycntl2;
  49.  static void param (short n);
  50. #else
  51.  #include <sys/param.h>
  52.  #include <sys/types.h>
  53.  #include <sys/file.h>
  54.  #ifdef __arm__
  55.   #include <sys/os.h>
  56.   #define printw  printf
  57.   #define scanw   scanf
  58.   float xmax,ymax;
  59.  #endif
  60.  #ifndef __arm__
  61.   #include <curses.h>
  62.  #endif
  63.  
  64.  #define scanz fflush(stdout),scanw
  65.  #define printz printw
  66.  
  67. /* <stdlib.h> */
  68. extern void *malloc (size_t);
  69. extern void exit (int);
  70. /* <string.h> */
  71. extern char *strcat (char *, const char *);
  72. extern int strcmp (const char *, const char *);
  73. extern char *strcpy (char *, const char *);
  74. /* <time.h> */
  75. extern long int time (long int *);
  76. #endif /* MSDOS */
  77.  
  78. #include "gnuchess.h"
  79.  
  80. #define pxx " PNBRQK"
  81. #define qxx " pnbrqk"
  82. #define rxx "12345678"
  83. #define cxx "abcdefgh"
  84. #define TAB (58)
  85. /* coordinates within a square for the following are ([1,5],[1,3]) */
  86. #define SQW (5)
  87. #define SQH (3)
  88. #define VIR_C(s)  ((flag.reverse) ? 7-column(s) : column(s))
  89. #define VIR_R(s)  ((flag.reverse) ? 7-row(s) : row(s))
  90. #define VSQ_X(x)  ((flag.reverse) ? SQW + 1 - (x) : (x))
  91. #define VSQ_Y(y)  ((flag.reverse) ? SQH + 1 - (y) : (y))
  92. #define Vblack(s) (!((VIR_C(s) + VIR_R(s)) % 2))
  93. /* Squares swapped */
  94. #define Vcoord(s,x,y) \
  95.         ((SQW)*(VIR_C(s)))+(x),((SQH)*(7-VIR_R(s))+(y))
  96. /* Squares and internal locations swapped */
  97. #define VcoordI(s,x,y) \
  98.         ((SQW)*(VIR_C(s)))+(VSQ_X(x)),((SQH)*(7-VIR_R(s))+(VSQ_Y(y)))
  99. /* Squares and internal rows swapped */
  100. #define VcoordR(s,x,y) \
  101.         ((SQW)*(VIR_C(s)))+(x),((SQH)*(7-VIR_R(s))+(VSQ_Y(y)))
  102. #ifdef __arm__
  103. #define VcoordX(s,x,y) ((SQW)*(VIR_C(s)))+(x)
  104. #define VcoordY(s,x,y) ((SQH)*(7-VIR_R(s))+(y))
  105. #endif /*__arm__*/
  106. static char mvstr[4][6];
  107. static char* ColorStr[2] = {"White", "Black"};
  108. static long evrate;
  109. short PositionFlag = 0;
  110. short coords = 1;
  111. #if defined(MSDOS) && !defined(SEVENBIT)
  112. short rv = 0;
  113. static void ONormal (void);
  114. static void OReverse (void);
  115. #else
  116. short stars = 0;
  117. short rv = 1;
  118. short shade = 0;
  119. #endif /* MSDOS && !SEVENBIT */
  120.  
  121. extern char *getenv (const char *);
  122. void TerminateSearch (int), Die (int);
  123.  
  124. void
  125. Initialize (void)
  126. {
  127. #ifdef __arm__
  128.   os_error *e;
  129.   char *sprite_file_path;
  130.   int r[10];
  131. #endif /*__arm__*/
  132.   signal (SIGINT, Die);
  133. #ifndef MSDOS
  134.   signal (SIGQUIT, Die);
  135.   initscr ();
  136. #ifndef __arm__
  137.   crmode ();
  138. #endif
  139. #else
  140.   mycntl1 = mycntl2 = 0;
  141. #endif /* MSDOS */
  142. #ifdef __arm__  /*Load Sprites */
  143.  r[0] = 10;
  144.  sprite_file_path = "<gnuchess$dir>.chess";
  145.  r[2] = (int) sprite_file_path; 
  146.  if(e = os_swi(0x2e,r))
  147.   {
  148.    fprintf(stdout,"%s not found",r[2]);
  149.   }
  150.  r[0]=-1;
  151.  r[1]=11;
  152.  os_swi(0x35,r);
  153.  xmax=r[2]+1;
  154.  r[1]=12;
  155.  os_swi(0x35,r);
  156.  ymax=r[2]+1;
  157. #endif /*__arm__*/
  158. }
  159.  
  160. void
  161. ExitChess (void)
  162. {
  163.   ListGame ();
  164.   gotoXY (1, 24);
  165. #ifndef MSDOS
  166. #ifndef __arm__
  167.   nocrmode ();
  168.   endwin ();
  169. #endif
  170. #endif /* MSDOS */
  171.   exit (0);
  172. }
  173.  
  174. void
  175. Die (int Sig)
  176. {
  177.   char s[80];
  178.  
  179.   signal (SIGINT, SIG_IGN);
  180. #ifdef MSDOS
  181.   Sig++;                                /* shut up the compiler */
  182. #else
  183.   signal (SIGQUIT, SIG_IGN);
  184. #endif /* MSDOS */
  185.   ShowMessage ("Abort? ");
  186.   scanz ("%s", s);
  187.   if (strcmp (s, "yes") == 0)
  188.     ExitChess ();
  189.   signal (SIGINT, Die);
  190. #ifndef MSDOS
  191.   signal (SIGQUIT, Die);
  192. #endif /* MSDOS */
  193. }
  194.  
  195. void
  196. TerminateSearch (int Sig)
  197. {
  198.   signal (SIGINT, SIG_IGN);
  199. #ifdef MSDOS
  200.   Sig++;                                /* shut up the compiler */
  201. #else
  202.   signal (SIGQUIT, SIG_IGN);
  203. #endif /* MSDOS */
  204.   flag.timeout = true;
  205.   flag.bothsides = false;
  206.   signal (SIGINT, Die);
  207. #ifndef MSDOS
  208.   signal (SIGQUIT, Die);
  209. #endif /* MSDOS */
  210. }
  211.  
  212. void
  213. algbr (short int f, short int t, short int flag)
  214.  
  215. /*
  216.    Generate move strings in different formats.
  217. */
  218.  
  219. {
  220.   int m3p;
  221.  
  222.   if (f != t)
  223.     {
  224.       /* algebraic notation */
  225.       mvstr[0][0] = cxx[column (f)];
  226.       mvstr[0][1] = rxx[row (f)];
  227.       mvstr[0][2] = cxx[column (t)];
  228.       mvstr[0][3] = rxx[row (t)];
  229.       mvstr[0][4] = mvstr[3][0] = '\0';
  230.       if ((mvstr[1][0] = pxx[board[f]]) == 'P')
  231.         {
  232.           if (mvstr[0][0] == mvstr[0][2])       /* pawn did not eat */
  233.             {
  234.               mvstr[2][0] = mvstr[1][0] = mvstr[0][2];  /* to column */
  235.               mvstr[2][1] = mvstr[1][1] = mvstr[0][3];  /* to row */
  236.               m3p = 2;
  237.             }
  238.           else
  239.             /* pawn ate */
  240.             {
  241.               mvstr[2][0] = mvstr[1][0] = mvstr[0][0];  /* from column */
  242.               mvstr[2][1] = mvstr[1][1] = mvstr[0][2];  /* to column */
  243.               mvstr[2][2] = mvstr[0][3];
  244.               m3p = 3;          /* to row */
  245.             }
  246.           mvstr[2][m3p] = mvstr[1][2] = '\0';
  247.           if (flag & promote)
  248.             {
  249.               mvstr[0][4] = mvstr[1][2] = mvstr[2][m3p] = qxx[flag & pmask];
  250.               mvstr[1][3] = mvstr[2][m3p + 1] = mvstr[0][5] = '\0';
  251.             }
  252.         }
  253.       else
  254.         /* not a pawn */
  255.         {
  256.           mvstr[2][0] = mvstr[1][0];
  257.           mvstr[2][1] = mvstr[0][1];
  258.           mvstr[2][2] = mvstr[1][1] = mvstr[0][2];      /* to column */
  259.           mvstr[2][3] = mvstr[1][2] = mvstr[0][3];      /* to row */
  260.           mvstr[2][4] = mvstr[1][3] = '\0';
  261.           strcpy (mvstr[3], mvstr[2]);
  262.           mvstr[3][1] = mvstr[0][0];
  263.           if (flag & cstlmask)
  264.             {
  265.               if (t > f)
  266.                 {
  267.                   strcpy (mvstr[1], "o-o");
  268.                   strcpy (mvstr[2], "O-O");
  269.                 }
  270.               else
  271.                 {
  272.                   strcpy (mvstr[1], "o-o-o");
  273.                   strcpy (mvstr[2], "O-O-O");
  274.                 }
  275.             }
  276.         }
  277.     }
  278.   else
  279.     mvstr[0][0] = mvstr[1][0] = mvstr[2][0] = mvstr[3][0] = '\0';
  280. }
  281.  
  282. int
  283. VerifyMove (char *s, short int iop, short unsigned int *mv)
  284.  
  285. /*
  286.    Compare the string 's' to the list of legal moves available for the
  287.    opponent. If a match is found, make the move on the board.
  288. */
  289.  
  290. {
  291.   static short pnt, tempb, tempc, tempsf, tempst, cnt;
  292.   static struct leaf xnode;
  293.   struct leaf *node;
  294.  
  295.   *mv = 0;
  296.   if (iop == 2)
  297.     {
  298.       UnmakeMove (opponent, &xnode, &tempb, &tempc, &tempsf, &tempst);
  299.       return (false);
  300.     }
  301.   cnt = 0;
  302.   MoveList (opponent, 2);
  303.   pnt = TrPnt[2];
  304.   while (pnt < TrPnt[3])
  305.     {
  306.       node = &Tree[pnt++];
  307.       algbr (node->f, node->t, (short) node->flags);
  308.       if (strcmp (s, mvstr[0]) == 0 || strcmp (s, mvstr[1]) == 0 ||
  309.           strcmp (s, mvstr[2]) == 0 || strcmp (s, mvstr[3]) == 0)
  310.         {
  311.           cnt++;
  312.           xnode = *node;
  313.         }
  314.     }
  315.   if (cnt == 1)
  316.     {
  317.       MakeMove (opponent, &xnode, &tempb, &tempc, &tempsf, &tempst, &INCscore);
  318.       if (SqAtakd (PieceList[opponent][0], computer))
  319.         {
  320.           UnmakeMove (opponent, &xnode, &tempb, &tempc, &tempsf, &tempst);
  321.           ShowMessage ("Illegal Move!!");
  322.           return (false);
  323.         }
  324.       else
  325.         {
  326.           if (iop == 1)
  327.             return (true);
  328.           UpdateDisplay (xnode.f, xnode.t, 0, (short) xnode.flags);
  329.           if ((board[xnode.t] == pawn)
  330.               || (xnode.flags & capture)
  331.               || (xnode.flags & cstlmask))
  332.             {
  333.               Game50 = GameCnt;
  334.               ZeroRPT ();
  335.             }
  336.           GameList[GameCnt].depth = GameList[GameCnt].score = 0;
  337.           GameList[GameCnt].nodes = 0;
  338.           ElapsedTime (1);
  339.           GameList[GameCnt].time = (short) et;
  340.           TimeControl.clock[opponent] -= et;
  341.           --TimeControl.moves[opponent];
  342.           *mv = (xnode.f << 8) | xnode.t;
  343.           algbr (xnode.f, xnode.t, false);
  344.           return (true);
  345.         }
  346.     }
  347.   if (cnt > 1)
  348.     ShowMessage ("Ambiguous Move!");
  349.   return (false);
  350. }
  351.  
  352. void
  353. help (void)
  354. {
  355.   ClrScreen ();
  356.   printz ("CHESS command summary\n");
  357.   printz ("g1f3     move from g1 to f3      quit      Exit Chess\n");
  358.   printz ("Nf3      move knight to f3       beep      on/off\n");
  359.   printz ("o-o      castle king side        easy      on/off\n");
  360.   printz ("o-o-o    castle queen side       hash      on/off\n");
  361.   printz ("bd       redraw board            reverse   board display\n");
  362.   printz ("list     game to chess.lst       book      on/off\n");
  363.   printz ("undo     undo last ply           remove    take back a move\n");
  364.   printz ("edit     edit board              force     enter game moves\n");
  365.   printz ("switch   sides with computer     both      computer match\n");
  366.   printz ("white    computer plays white    black     computer plays black\n");
  367.   printz ("depth    set search depth        level     select level\n");
  368.   printz ("post     principle variation     hint      suggest a move\n");
  369.   printz ("save     game to file            get       game from file\n");
  370.   printz ("random   randomize play          new       start new game\n");
  371. #ifndef __arm__
  372.   printz ("rv       toggle reverse video    coords    toggle coords\n");
  373. #endif
  374. #if (!defined(MSDOS) || defined(SEVENBIT))&& !defined(__arm__)
  375.   printz ("shade    toggle shade black      stars     toggle stars\n");
  376. #endif /* !MSDOS || SEVENBIT */
  377. #ifndef __arm__
  378.   printz ("p        show coordinate values\n");
  379. #endif
  380.   gotoXY (10, 21);
  381.   printz ("Computer: %s", ColorStr[computer]);
  382.   gotoXY (10, 22);
  383.   printz ("Opponent: %s", ColorStr[opponent]);
  384.   gotoXY (10, 23);
  385.   printz ("Level: %ld", Level);
  386.   gotoXY (10, 24);
  387.   printz ("Easy mode: %s", (flag.easy) ? "ON" : "OFF");
  388.   gotoXY (40, 21);
  389.   printz ("Depth: %d", MaxSearchDepth);
  390.   gotoXY (40, 22);
  391.   printz ("Random: %s", (dither) ? "ON" : "OFF");
  392.   gotoXY (40, 23);
  393.   printz ("Transposition table: %s", (flag.hash) ? "ON" : "OFF");
  394.   gotoXY (40, 24);
  395.   printz ("Hit <RET> to return: ");
  396. #ifndef __arm__
  397.   refresh ();
  398. #endif  
  399.   fflush(stdin);
  400.   getchar();
  401.   ClrScreen ();
  402.   UpdateDisplay (0, 0, 1, 0);
  403. }
  404.  
  405. void
  406. EditBoard (void)
  407.  
  408. /*
  409.   Set up a board position. Pieces are entered by typing the piece
  410.   followed by the location. For example, Nf3 will place a knight on
  411.   square f3.
  412. */
  413.  
  414. {
  415.   short a, r, c, sq, i;
  416.   char s[80];
  417.  
  418.   ClrScreen ();
  419.   UpdateDisplay (0, 0, 1, 0);
  420.   gotoXY (TAB, 3);
  421.   printz (".   Exit to main");
  422.   gotoXY (TAB, 4);
  423.   printz ("#   Clear board");
  424.   gotoXY (TAB, 5);
  425.   printz ("c   Change sides");
  426.   gotoXY (TAB, 7);
  427.   printz ("Enter piece & location: ");
  428.   a = white;
  429.   do
  430.     {
  431.       gotoXY (TAB, 6);
  432.       printz ("Editing: %s", ColorStr[a]);
  433.       gotoXY (TAB + 24, 7);
  434. #ifndef __arm__
  435.       ClrEoln ();
  436. #endif
  437.       scanz ("%s", s);
  438.       if (s[0] == '#')
  439.         {
  440.           for(sq = 0; sq < 64; sq++)
  441.             {
  442.               board[sq] = no_piece;
  443.               color[sq] = neutral;
  444.               DrawPiece (sq);
  445.             }
  446.         }
  447.       if (s[0] == 'c' || s[0] == 'C')
  448.         a = otherside[a];
  449.       c = s[1] - 'a';
  450.       r = s[2] - '1';
  451.       if ((c >= 0) && (c < 8) && (r >= 0) && (r < 8))
  452.         {
  453.           sq = locn (r, c);
  454.           for (i = king; i > no_piece; i--)
  455.             if ((s[0] == pxx[i]) || (s[0] == qxx[i]))
  456.               break;
  457.           board[sq] = i;
  458.           color[sq] = (board[sq] == no_piece) ? neutral : a;    
  459.           DrawPiece (sq);
  460.         }
  461.   } while (s[0] != '.');
  462.  
  463.   for (sq = 0; sq < 64; sq++)
  464.     Mvboard[sq] = (board[sq] != Stboard[sq]) ? 10 : 0;
  465.   GameCnt = 0;
  466.   Game50 = 1;
  467.   ZeroRPT ();
  468.   Sdepth = 0;
  469.   InitializeStats ();
  470.   ClrScreen ();
  471.   UpdateDisplay (0, 0, 1, 0);
  472. }
  473.  
  474. void
  475. ShowPlayers (void)
  476. {      
  477.   gotoXY (TAB, ((flag.reverse) ? 23 : 2));
  478.   printz ("%s", (computer == black) ? "Computer" : "Human   ");
  479.   gotoXY (TAB, ((flag.reverse) ? 2 : 23));
  480.   printz ("%s", (computer == white) ? "Computer" : "Human   ");
  481. }
  482.  
  483. void
  484. ShowDepth (char ch)
  485. {
  486.   gotoXY (TAB, 4);
  487.   printz ("Depth= %d%c ", Sdepth, ch);
  488. #ifndef __arm__
  489.   ClrEoln ();
  490. #endif
  491. }
  492.  
  493. void
  494. ShowScore (short score)
  495. {
  496.   gotoXY (TAB, 5);
  497.   printz ("Score= %d", score);
  498. #ifndef __arm__
  499.   ClrEoln ();
  500. #endif
  501. }
  502.  
  503. void
  504. ShowMessage (char *s)
  505. {
  506.   gotoXY (TAB, 6);
  507.   printz ("%s", s);
  508. #ifndef __arm__
  509.   ClrEoln ();
  510. #endif
  511. }
  512.  
  513. void
  514. ClearMessage (void)
  515. {
  516.   gotoXY (TAB, 6);
  517.   ClrEoln ();
  518. }
  519.  
  520. void
  521. ShowCurrentMove (short int pnt, short int f, short int t)
  522. {
  523.   algbr (f, t, false);
  524.   gotoXY (TAB, 7);
  525.   printz ("(%2d) %4s", pnt, mvstr[0]);
  526. }
  527.  
  528. void
  529. ShowHeader (void)
  530. {
  531.   gotoXY (TAB, 10);
  532. #ifdef MSDOS
  533.   printz ("GNU Chess display (MS-DOS, Mar 90)");
  534. #else
  535.  #ifndef __arm__
  536.   printz ("GNU Chess display (Nov 89)");
  537.  #else
  538.   printz ("GNU Chess (Nov 89)");
  539.  #endif
  540. #endif /* MSDOS */
  541. }
  542.  
  543. void
  544. ShowSidetomove (void)
  545. {
  546.   gotoXY (TAB, 14);
  547.   printz ("%2d:   %s", 1 + GameCnt / 2, ColorStr[player]);
  548.   ClrEoln ();
  549. }
  550.  
  551. void
  552. ShowPrompt (void)
  553. {
  554.   gotoXY (TAB, 19);
  555.   printz ("Your move is? ");
  556.   ClrEoln ();
  557. }
  558.  
  559. void
  560. ShowNodeCnt (long int NodeCnt, long int evrate)
  561. {      
  562.   gotoXY (TAB, 21);
  563.   printz ("Nodes= %8ld, Nodes/Sec= %5ld", NodeCnt, evrate);
  564.   ClrEoln ();
  565. }  
  566.  
  567. void
  568. ShowResults (short int score, short unsigned int *bstline, char ch)
  569. {
  570.   unsigned char d, ply;
  571.   if (flag.post)
  572.     {
  573.       ShowDepth (ch);
  574.       ShowScore (score);
  575.       d = 7;
  576.       for (ply = 1; bstline[ply] > 0; ply++)
  577.         {
  578.           if (ply % 4 == 1)
  579.             {
  580.               gotoXY (TAB, ++d);
  581.             #ifndef __arm__
  582.               ClrEoln ();
  583.             #endif
  584.             }
  585.           algbr ((short) bstline[ply] >> 8, (short) bstline[ply] & 0xFF, false);
  586.           printz ("%5s ", mvstr[0]);
  587.         }
  588.     #ifndef __arm__
  589.       ClrEoln ();       
  590.     #endif
  591.       while (d < 13)
  592.         {
  593.           gotoXY (TAB, ++d);
  594.         #ifndef __arm__
  595.           ClrEoln ();
  596.         #endif
  597.         }
  598.     }
  599. }
  600.  
  601. void
  602. SearchStartStuff (short int side)
  603. {
  604.   short i;
  605.   
  606.   signal (SIGINT, TerminateSearch);
  607. #ifdef MSDOS
  608.   side++;                               /* shut up the compiler */
  609. #else
  610.   signal (SIGQUIT, TerminateSearch);
  611. #endif /* MSDOS */
  612.   for (i = 4; i < 14; i++)
  613.     {
  614.       gotoXY (TAB, i);
  615.     #ifndef __arm__
  616.       ClrEoln ();
  617.     #endif
  618.     }
  619. }
  620.  
  621. void
  622. OutputMove (void)
  623. {
  624.   int i;
  625.  
  626.   UpdateDisplay (root->f, root->t, 0, (short) root->flags);
  627.   gotoXY (TAB, 17);
  628.   printz ("My move is: %s", mvstr[0]);
  629.   if (flag.beep)
  630.     putchar (7);
  631. #ifndef __arm__
  632.   ClrEoln ();
  633. #endif
  634.  
  635.   gotoXY (TAB, 24);
  636.   if (root->flags & draw)
  637.     {printz ("Drawn game!");}
  638.   else if (root->score == -9999)
  639.     {printz ("Opponent mates!");}
  640.   else if (root->score == 9998)
  641.     {printz ("Computer mates!");}
  642.   else if (root->score < -9000)
  643.     {printz ("Opponent will soon mate!");}
  644.   else if (root->score > 9000)
  645.     {printz ("Computer will soon mate!");}
  646. #ifndef __arm__
  647.   ClrEoln ();
  648. #endif
  649.  
  650.   if (flag.post)
  651.     {
  652.       ShowNodeCnt (NodeCnt, evrate);
  653.       gotoXY (TAB, 22);
  654.       for (i = 1999; i >= 0 && Tree[i].f == 0 && Tree[i].t == 0; i--);
  655.       printz ("Max Tree= %5d", i);
  656. #ifndef __arm__
  657.       ClrEoln ();
  658.     #endif
  659.     }
  660. }
  661.  
  662. void
  663. ElapsedTime (short int iop)
  664.  
  665. /*
  666.   Determine the time that has passed since the search was started. If
  667.   the elapsed time exceeds the target (ResponseTime+ExtraTime) then set
  668.   timeout to true which will terminate the search.
  669. */
  670.  
  671. {
  672.   et = time ((long *) 0) - time0;
  673.   if (et < 0)
  674.     et = 0;
  675.   ETnodes += 50;
  676.   if (et > et0 || iop == 1)
  677.     {
  678.       if (et > ResponseTime + ExtraTime && Sdepth > 1)
  679.         flag.timeout = true;
  680.       et0 = et;
  681.       if (iop == 1)
  682.         {
  683.           time0 = time ((long *) 0);
  684.           et0 = 0;
  685.         }
  686.       if (et > 0)
  687.         /* evrate used to be Nodes / cputime I dont` know why */
  688.         evrate = NodeCnt / (et + ft);
  689.       else
  690.         evrate = 0;
  691.       ETnodes = NodeCnt + 50;
  692.       UpdateClocks ();
  693.     }
  694. }
  695.  
  696. void
  697. UpdateClocks (void)
  698. {
  699.   short m, s;
  700.   m = (short) (et / 60);
  701.   s = (short) (et - 60 * (long) m);
  702.   if (TCflag)
  703.     {
  704.       m = (short) ((TimeControl.clock[player] - et) / 60);
  705.       s = (short) (TimeControl.clock[player] - et - 60 * (long) m);
  706.     }
  707.   if (m < 0)
  708.     m = 0;
  709.   if (s < 0)
  710.     s = 0;
  711.   if (player == white)
  712.     gotoXY (TAB+9, (flag.reverse) ? 2 : 23);
  713.   else
  714.     gotoXY (TAB+9, (flag.reverse) ? 23 : 2);
  715.   printz ("%d:%02d   ", m, s);
  716.   if (flag.post)
  717.     ShowNodeCnt (NodeCnt, evrate);
  718. #ifndef __arm__
  719.   refresh ();
  720. #endif  
  721. }
  722.  
  723.  
  724. void
  725. SetTimeControl (void)
  726. {
  727.   if (TCflag)
  728.     {
  729.       TimeControl.moves[white] = TimeControl.moves[black] = TCmoves;
  730.       TimeControl.clock[white] = TimeControl.clock[black] = 60 * (long) TCminutes;
  731.     }
  732.   else
  733.     {
  734.       TimeControl.moves[white] = TimeControl.moves[black] = 0;
  735.       TimeControl.clock[white] = TimeControl.clock[black] = 0;
  736.       Level = 60 * (long) TCminutes;
  737.     }
  738.   et = 0;
  739.   ElapsedTime (1);
  740. }
  741.  
  742. void
  743. gotoXY (short int x, short int y)
  744. {
  745. #ifdef MSDOS
  746.   putchar(ESC);
  747.   putchar('[');
  748.   param(y);
  749.   putchar(';');
  750.   param(x);
  751.   putchar('H');
  752. #else
  753.   #ifndef __arm__
  754.     move (y - 1, x - 1);
  755.   #else
  756.     os_swi(0x11f,NULL);
  757.     os_swi(0xff+x,NULL);
  758.     os_swi(0xff+y,NULL);
  759.   #endif
  760. #endif /* MSDOS */
  761. }
  762.  
  763. void
  764. ClrScreen (void)
  765. {
  766. #ifdef MSDOS
  767.   putchar(ESC);
  768.   putchar('[');
  769.   putchar('2');
  770.   putchar('J');
  771. #else
  772.   clear ();
  773. #endif /* MSDOS */
  774. #ifndef __arm__
  775.   refresh ();
  776. #endif  
  777. }
  778.  
  779. void
  780. ClrEoln (void)
  781. {
  782. #ifdef MSDOS
  783.   putchar(ESC);
  784.   putchar('[');
  785.   putchar('K');
  786. #else
  787.   clrtoeol ();
  788. #endif /* MSDOS */
  789. #ifndef __arm__
  790.   refresh ();
  791. #endif  
  792. }
  793.  
  794. #ifdef MSDOS
  795. void
  796. param(short n)
  797. {
  798.   if (n >= 10)
  799.     {
  800.     register short d, q;
  801.     q = n/10; d = n%10;
  802.     putchar(q + '0');
  803.     putchar(d + '0');
  804.   }
  805.   else
  806.     putchar(n + '0');
  807. }
  808. #endif /* MSDOS */
  809.  
  810. void
  811. OReverse()
  812. {
  813. #ifdef MSDOS
  814.   putchar (ESC);
  815.   putchar ('[');
  816.   param (7);
  817.   putchar ('m');
  818. #else
  819.   standout ();
  820. /* attron (A_REVERSE); */
  821. #endif /* MSDOS */
  822. }
  823.  
  824. void
  825. ONormal()
  826. {
  827. #ifdef MSDOS
  828.   putchar (ESC);
  829.   putchar ('[');
  830.   param (0);
  831.   putchar ('m');
  832. #else
  833.   standend ();
  834. /* attroff (A_REVERSE);*/
  835. #endif /* MSDOS */
  836. }
  837.  
  838. #ifndef __arm__
  839. void
  840. DrawPiece (short int sq)
  841. {
  842.   gotoXY (VcoordR (sq, 2, 2));
  843.  
  844.   switch (color[sq])
  845.     {
  846.     case black:
  847.       if (rv)
  848.         OReverse ();
  849. #if defined(MSDOS) && !defined(SEVENBIT)
  850.       printz (" %c ", pxx[board[sq]]);
  851. #else
  852.       printz ((stars ? "*%c*" : " %c "), pxx[board[sq]]);
  853. #endif /* MSDOS && !SEVENBIT */
  854.       ONormal ();
  855.       break;
  856.     case neutral:
  857. #if defined(MSDOS) && !defined(SEVENBIT)
  858.       if (rv)
  859.         printz (Vblack (sq) ? "\262\262\262" : "\260\260\260");
  860.       else
  861.         printz (Vblack (sq) ? "\260\260\260" : "\262\262\262");
  862. #else
  863.       if (shade)
  864.         {printz (Vblack (sq) ? "///" : "   ");}
  865.       else
  866.         {
  867.           if (Vblack (sq))
  868.             OReverse ();
  869.           printz ("   ");
  870.           ONormal ();
  871.         }
  872. #endif /* MSDOS && !SEVENBIT */
  873.       break;
  874.     case white:
  875. #if defined(MSDOS) && !defined(SEVENBIT)
  876.       if (!rv)
  877.         OReverse ();
  878.       printz (" %c ", pxx[board[sq]]);
  879.       ONormal ();
  880. #else
  881.       printz (" %c ", pxx[board[sq]]);
  882. #endif /* MSDOS && !SEVENBIT */
  883.       break;
  884.     default:
  885.       ShowMessage ("DrawPiece:  color[sq] err");
  886.       break;
  887.     }
  888. }
  889. #else
  890. void
  891. DrawPiece (short int sq)
  892. {
  893.   char  *sprite_name;
  894.   char  *sprite_blank;
  895.   os_error *e;
  896.   int r[10];
  897.   int arm_posx,arm_posy;
  898.   char my_pxx;
  899.   
  900.   my_pxx = pxx[board[sq]];
  901.   if(color[sq] == white)
  902.         my_pxx = tolower(my_pxx);
  903.   
  904.   arm_posx = VcoordX (sq, 2, 2);
  905.   arm_posy = VcoordY (sq, 2, 2);
  906.   
  907.   arm_posy = 1024-arm_posy*35-112;
  908.   arm_posx = arm_posx*21+8;
  909.   
  910.   switch(my_pxx)
  911.   {
  912.         case'P': sprite_name = "sch_bauer";
  913.                 break;
  914.         case'R': sprite_name = "sch_turm";
  915.                 break;
  916.         case'B': sprite_name = "sch_laeufer";
  917.                 break;
  918.         case'N': sprite_name = "sch_springer";
  919.                 break;
  920.         case'Q': sprite_name = "sch_dame";
  921.                 break;
  922.         case'K': sprite_name = "sch_koenig";
  923.                 break;
  924.         case'p': sprite_name = "wei_bauer";
  925.                 break;
  926.         case'r': sprite_name = "wei_turm";
  927.                 break;
  928.         case'b': sprite_name = "wei_laeufer";
  929.                 break;
  930.         case'n': sprite_name = "wei_springer";
  931.                 break;
  932.         case'q': sprite_name = "wei_dame";
  933.                 break;
  934.         case'k': sprite_name = "wei_koenig";
  935.                 break;
  936.         default:if ( pxx[board[sq]] != 32)
  937.                 fprintf(stdout,"Unknown figure !!!! found: %c",pxx[board[sq]]);
  938.   }
  939.         if(Vblack(sq))
  940.          {
  941.                   sprite_blank = "blk_leer";
  942.          }
  943.          else{
  944.                   sprite_blank = "wht_leer";
  945.          }
  946.         
  947.         r[0]=34;
  948.         r[2]=(int) sprite_blank;
  949.         r[3]=arm_posx;
  950.         r[4]=arm_posy;
  951.         r[5]=0;
  952.         if(e = os_swi(0x2e,r))
  953.     {
  954.      fprintf(stdout,"%s not found",r[2]);
  955.     }
  956.  
  957.         if ( pxx[board[sq]] != 32){
  958.         r[0]=34;
  959.         r[2]=(int) sprite_name;
  960.         r[3]=arm_posx;
  961.         r[4]=arm_posy;
  962.         r[5]=8;
  963.         if(e = os_swi(0x2e,r))
  964.     {
  965.      fprintf(stdout,"%s not found",r[2]);
  966.     }
  967.         }
  968. }
  969. #endif /*__arm__*/
  970.  
  971.  
  972.  
  973.  
  974. #ifndef __arm__
  975. void
  976. DrawSquare (short int sq)
  977. {
  978. #if defined(MSDOS) && !defined(SEVENBIT)
  979.   if (rv)
  980.     {
  981.       gotoXY (Vcoord (sq, 1, 1));
  982.       printz (Vblack (sq) ? "\262\262\262\262\262" : "\260\260\260\260\260");
  983.       gotoXY (Vcoord (sq, 1, 2));
  984.       printz (Vblack (sq) ? "\262\262\262\262\262" : "\260\260\260\260\260");
  985.       gotoXY (Vcoord (sq, 1, 3));
  986.       printz (Vblack (sq) ? "\262\262\262\262\262" : "\260\260\260\260\260");
  987.     }
  988.   else
  989.     {
  990.       gotoXY (Vcoord (sq, 1, 1));
  991.       printz (Vblack (sq) ? "\260\260\260\260\260" : "\262\262\262\262\262");
  992.       gotoXY (Vcoord (sq, 1, 2));
  993.       printz (Vblack (sq) ? "\260\260\260\260\260" : "\262\262\262\262\262");
  994.       gotoXY (Vcoord (sq, 1, 3));
  995.       printz (Vblack (sq) ? "\260\260\260\260\260" : "\262\262\262\262\262");
  996.     }
  997. #else
  998.   if (shade)
  999.     {
  1000.       gotoXY (Vcoord (sq, 1, 1));
  1001.       printz (Vblack (sq) ? "/////" : "     ");
  1002.       gotoXY (Vcoord (sq, 1, 2));
  1003.       printz (Vblack (sq) ? "/////" : "     ");
  1004.       gotoXY (Vcoord (sq, 1, 3));
  1005.       printz (Vblack (sq) ? "/////" : "     ");
  1006.     }
  1007.   else
  1008.     {
  1009.       if (Vblack (sq))
  1010.         OReverse ();
  1011.       gotoXY (Vcoord (sq, 1, 1));
  1012.       printz ("     ");
  1013.       gotoXY (Vcoord (sq, 1, 2));
  1014.       printz ("     ");
  1015.       gotoXY (Vcoord (sq, 1, 3));
  1016.       printz ("     ");
  1017.       ONormal ();
  1018.     }
  1019. #endif /* MSDOS && !SEVENBIT */
  1020. }
  1021. #else
  1022. void
  1023. DrawSquare (short int sq)
  1024. {
  1025.         int r[10];
  1026.         char *chess_board;
  1027.         os_error *e;
  1028.   
  1029.         if(!flag.reverse)
  1030.                 chess_board = "board";
  1031.         else
  1032.                 chess_board = "boardr"; 
  1033.                 
  1034.         r[0] = 34;
  1035.         r[2] = (int) chess_board;
  1036.         r[3] = 0;
  1037.         r[4] = 32;
  1038.         r[5] = 8;
  1039.         os_swi(0x2e,r);
  1040.  
  1041. }
  1042. #endif /*__arm__*/
  1043.  
  1044. void
  1045. DrawCoords (void)
  1046. {
  1047.   short z;
  1048.  
  1049.   for (z = 0; z <= 7; z++)
  1050.     {
  1051.       short sq;
  1052.  
  1053.       sq = z << 3;
  1054.       gotoXY (VcoordI (sq, 1, 1));
  1055. #if !defined(MSDOS) || defined(SEVENBIT)
  1056.       if ((Vblack (sq) || shade) && rv)
  1057. #endif /* !MSDOS || SEVENBIT */
  1058.         OReverse ();
  1059.       printz ("%d", 1 + z);
  1060.       ONormal ();
  1061.     }
  1062.  
  1063.   for (z = 0; z <= 7; z++)
  1064.     {
  1065.       short sq;
  1066.  
  1067.       sq = z;
  1068.       gotoXY (VcoordI (sq, SQW, SQH));
  1069. #if !defined(MSDOS) || defined(SEVENBIT)
  1070.       if ((Vblack (sq) || shade) && rv)
  1071. #endif /* !MSDOS || SEVENBIT */
  1072.         OReverse ();
  1073.       printz ("%c", cxx[z]);
  1074.       ONormal ();
  1075.     }
  1076.  
  1077. #if !defined(MSDOS) || defined(SEVENBIT)
  1078.   for (z = 1; z <= (8 * SQH); z++)
  1079.     {
  1080.       gotoXY ((8 * SQW) + 1, z);
  1081.       printz ("|");
  1082.     }
  1083. #endif /* MSDOS && !SEVENBIT */
  1084. }
  1085.  
  1086. void
  1087. ShowPostnValue (short int sq)
  1088.  
  1089. /*
  1090.   must have called ExaminePosition() first
  1091. */
  1092.      
  1093. {
  1094.   short score;
  1095.   
  1096.   gotoXY (VcoordR (sq, 2, 1));
  1097.   ScorePosition (color[sq], &score);
  1098. #if !defined(MSDOS) || defined(SEVENBIT)
  1099.   if (Vblack (sq) && !shade)
  1100.     OReverse ();
  1101. #endif /* !MSDOS || SEVENBIT */
  1102.  
  1103.   if (color[sq] != neutral)
  1104.     {printz ("%3d", svalue[sq]);}
  1105.   else
  1106. #if defined(MSDOS) && !defined(SEVENBIT)
  1107.     {
  1108.       if (rv)
  1109.         {printz (Vblack (sq) ? "\262\262\262" : "\260\260\260");}
  1110.       else
  1111.         {printz (Vblack (sq) ? "\260\260\260" : "\262\262\262");}
  1112.     }
  1113. #else
  1114.     {printz (shade && Vblack (sq) ? "///" : "   ");}
  1115. #endif /* MSDOS && !SEVENBIT */
  1116.   ONormal ();
  1117. }
  1118.  
  1119. void
  1120. ShowPostnValues (void)
  1121. {
  1122.   short sq, score;
  1123.  
  1124.   ExaminePosition ();
  1125.   for (sq = 0; sq < 64; sq++)
  1126.     ShowPostnValue (sq);
  1127.   ScorePosition (opponent, &score);
  1128.   ShowScore (score);
  1129. }
  1130.  
  1131. void
  1132. UpdateDisplay (short int f, short int t, short int redraw, short int isspec)
  1133. {
  1134.   short sq;
  1135.   
  1136.   if (redraw)
  1137.     {
  1138.       ShowHeader ();
  1139.       ShowPlayers ();
  1140. #ifdef __arm__
  1141.       DrawSquare (sq); 
  1142. #endif      
  1143.       for (sq = 0; sq < 64; sq++)
  1144.         {
  1145. #ifndef __arm__
  1146.           DrawSquare (sq);
  1147. #endif
  1148.           DrawPiece (sq);
  1149.         }
  1150. #ifndef __arm__
  1151.       if (coords)
  1152.         DrawCoords ();
  1153. #endif /*arm*/
  1154.     }
  1155.   else
  1156.     {
  1157.       DrawPiece (f);
  1158.       DrawPiece (t);
  1159.       if (isspec & cstlmask)
  1160.         if (t > f)
  1161.           {
  1162.             DrawPiece (f + 3);
  1163.             DrawPiece (t - 1);
  1164.           }
  1165.         else
  1166.           {
  1167.             DrawPiece (f - 4);
  1168.             DrawPiece (t + 1);
  1169.           }
  1170.       else if (isspec & epmask)
  1171.         {
  1172.           DrawPiece (t - 8);
  1173.           DrawPiece (t + 8);
  1174.         }
  1175.     }
  1176.   if (PositionFlag)
  1177.     ShowPostnValues ();
  1178. #ifndef __arm__
  1179.   refresh ();
  1180. #endif  
  1181. }
  1182.  
  1183. void
  1184. GetGame (void)
  1185. {
  1186.   FILE *fd;
  1187.   char fname[256], tname[256];
  1188.   char *tmp;
  1189.   int c;
  1190.   short sq;
  1191.   unsigned short m;
  1192.  
  1193.   tname[0] = 0;
  1194.  
  1195.   if (tmp = getenv ("HOME"))
  1196.     strcpy (fname, tmp);
  1197.   else
  1198.     fname[0] = '\0';
  1199.   strcat (fname, "/");
  1200.  
  1201.   ShowMessage ("File name: ");
  1202.   scanz ("%s", tname);
  1203.  
  1204.   if (tname[0])
  1205.     strcat (fname, tname);
  1206.   else
  1207.     strcat (fname, "chess.000");
  1208.  
  1209.   ShowMessage("Loading ");
  1210.   printz ("%s", fname);
  1211.  
  1212.   if ((fd = fopen (fname, "r")) == NULL)
  1213.     {
  1214.       ShowMessage ("Load failed");
  1215.       return;
  1216.     }
  1217.  
  1218.   fscanf (fd, "%hd%hd%hd", &computer, &opponent, &Game50);
  1219.   fscanf (fd, "%hd%hd", &castld[white], &castld[black]);
  1220.   fscanf (fd, "%hd%hd", &TCflag, &OperatorTime);
  1221.   fscanf (fd, "%ld%ld%hd%hd",
  1222.           &TimeControl.clock[white], &TimeControl.clock[black],
  1223.           &TimeControl.moves[white], &TimeControl.moves[black]);
  1224.   for (sq = 0; sq < 64; sq++)
  1225.     {
  1226.       fscanf (fd, "%hd%hd", &m, &Mvboard[sq]);
  1227.       board[sq] = (m >> 8);
  1228.       color[sq] = (m & 0xFF);
  1229.       if (color[sq] == 0)
  1230.         color[sq] = neutral;
  1231.       else
  1232.         --color[sq];
  1233.     }
  1234.   GameCnt = 0;
  1235.   c = '?';
  1236.   while (c != EOF)
  1237.     {
  1238.       ++GameCnt;
  1239.       c = fscanf (fd, "%hd%hd%hd%ld%hd%hd%hd", &GameList[GameCnt].gmove,
  1240.                   &GameList[GameCnt].score, &GameList[GameCnt].depth,
  1241.                   &GameList[GameCnt].nodes, &GameList[GameCnt].time,
  1242.                   &GameList[GameCnt].piece, &GameList[GameCnt].color);
  1243.       if (GameList[GameCnt].color == 0)
  1244.         GameList[GameCnt].color = neutral;
  1245.       else
  1246.         --GameList[GameCnt].color;
  1247.     }
  1248.   GameCnt--;
  1249.   if (TimeControl.clock[white] > 0)
  1250.     TCflag = true;
  1251.   computer--;
  1252.   opponent--;
  1253.  
  1254.   fclose (fd);
  1255.  
  1256.   InitializeStats ();
  1257.   Sdepth = 0;
  1258.   ShowMessage ("Load done.  Press <Ret>");
  1259.   fflush (stdin);
  1260.   getchar ();
  1261.   UpdateDisplay (0, 0, 1, 0);
  1262.  
  1263. }
  1264.  
  1265. void
  1266. SaveGame (void)
  1267. {
  1268.   FILE *fd;
  1269.   char fname[256], tname[256];
  1270.   char *tmp;
  1271.   short sq, i, c;
  1272.  
  1273.   tname[0] = 0;
  1274.  
  1275.   if (tmp = getenv ("HOME"))
  1276.     strcpy (fname, tmp);
  1277.   else
  1278.     fname[0] = '\0';
  1279.   strcat (fname, "<gnuchess$dir>.");
  1280.  
  1281.   ShowMessage ("File name: ");
  1282. #ifndef __arm__
  1283.   refresh ();
  1284. #endif  
  1285.   scanz ("%s", tname);
  1286.  
  1287.   if (tname[0])
  1288.     strcat (fname, tname);
  1289.   else
  1290.     strcat (fname, "chess_000");
  1291.  
  1292.   ShowMessage("Saving ");
  1293.   printz ("%s", fname);
  1294.  
  1295.   if (NULL == (fd = fopen (fname, "w")))
  1296.     {
  1297.       ShowMessage ("Not saved");
  1298.       return;
  1299.     }
  1300.  
  1301.   fprintf (fd, "%d %d %d\n", computer + 1, opponent + 1, Game50);
  1302.   fprintf (fd, "%d %d\n", castld[white], castld[black]);
  1303.   fprintf (fd, "%d %d\n", TCflag, OperatorTime);
  1304.   fprintf (fd, "%ld %ld %d %d\n",
  1305.            TimeControl.clock[white], TimeControl.clock[black],
  1306.            TimeControl.moves[white], TimeControl.moves[black]);
  1307.   for (sq = 0; sq < 64; sq++)
  1308.     {
  1309.       if (color[sq] == neutral)
  1310.         c = 0;
  1311.       else
  1312.         c = color[sq] + 1;
  1313.       fprintf (fd, "%d %d\n", 256 * board[sq] + c, Mvboard[sq]);
  1314.     }
  1315.   for (i = 1; i <= GameCnt; i++)
  1316.     {
  1317.       if (GameList[i].color == neutral)
  1318.         c = 0;
  1319.       else
  1320.         c = GameList[i].color + 1;
  1321.       fprintf (fd, "%d %d %d %ld %d %d %d\n",
  1322.                GameList[i].gmove, GameList[i].score, GameList[i].depth,
  1323.                GameList[i].nodes, GameList[i].time,
  1324.                GameList[i].piece, c);
  1325.     }
  1326.   fclose (fd);
  1327.   ShowMessage ("Save done.  Press <Ret>");
  1328.   fflush (stdin);
  1329.   getchar ();
  1330. }
  1331.  
  1332. void
  1333. ListGame (void)
  1334. {
  1335.   FILE *fd;
  1336.   char fname[256];
  1337.   char *tmp;
  1338.   short i, f, t;
  1339.  
  1340.   if (tmp = getenv ("HOME"))
  1341.     strcpy (fname, tmp);
  1342.   else
  1343.     fname[0] = '\0';
  1344.   strcat (fname, "<gnuchess$dir>.chess_lst");
  1345.  
  1346.   if (fd = fopen (fname, "w"))
  1347.     ShowMessage ("Writing chess_lst");
  1348.   else
  1349.     {
  1350.       ShowMessage ("Cannot write chess_lst");
  1351.       return;
  1352.     }
  1353.  
  1354.   fprintf (fd, "\n");
  1355.   fprintf (fd, "       score  depth   nodes  time         ");
  1356.   fprintf (fd, "       score  depth   nodes  time\n");
  1357.   for (i = 1; i <= GameCnt; i++)
  1358.     {
  1359.       f = GameList[i].gmove >> 8;
  1360.       t = (GameList[i].gmove & 0xFF);
  1361.       algbr (f, t, false);
  1362.       if ((i % 2) == 0)
  1363.         fprintf (fd, "\n");
  1364.       else
  1365.         fprintf (fd, "         ");
  1366.       fprintf (fd, "%5s  %5d     %2d %7ld %5d", mvstr[0],
  1367.                GameList[i].score, GameList[i].depth,
  1368.                GameList[i].nodes, GameList[i].time);
  1369.     }
  1370.   fprintf (fd, "\n\n");
  1371.   fclose (fd);
  1372.   ShowMessage ("chess_lst written");
  1373. }
  1374.  
  1375. void
  1376. Undo (void)
  1377.  
  1378. /*
  1379.   Undo the most recent half-move.
  1380. */
  1381.  
  1382. {
  1383.   short f, t;
  1384.   f = GameList[GameCnt].gmove >> 8;
  1385.   t = GameList[GameCnt].gmove & 0xFF;
  1386.   if (board[t] == king && distance (t, f) > 1)
  1387.     (void) castle (GameList[GameCnt].color, f, t, 2);
  1388.   else
  1389.     {
  1390.       /* Check for promotion: */
  1391.       if ((color[t] == white && row (f) == 6 && row (t) == 7)
  1392.           || (color[t] == black && row (f) == 1 && row (t) == 0))
  1393.         {
  1394.           int g, from = f;
  1395.           for (g = GameCnt - 1; g > 0; g--)
  1396.             if (GameList[g].gmove & 0xFF == from)
  1397.               from = GameList[g].gmove >> 8;
  1398.           if ((color[t] == white && row (from) == 1)
  1399.               || (color[t] == black && row (from) == 6))
  1400.             board[t] = pawn;
  1401.         }
  1402.       board[f] = board[t];
  1403.       color[f] = color[t];
  1404.       board[t] = GameList[GameCnt].piece;
  1405.       color[t] = GameList[GameCnt].color;
  1406.       if (color[t] != neutral)
  1407.         Mvboard[t]--;
  1408.       Mvboard[f]--;
  1409.     }
  1410.   if (TCflag)
  1411.     ++TimeControl.moves[color[f]];
  1412.   GameCnt--;
  1413.   computer = otherside[computer];
  1414.   opponent = otherside[opponent];
  1415.   flag.mate = false;
  1416.   Sdepth = 0;
  1417.   UpdateDisplay (0, 0, 1, 0);
  1418.   InitializeStats ();
  1419. }
  1420.  
  1421. void
  1422. ChangeAlphaWindow (void)
  1423. {
  1424.   ShowMessage ("Awindow= ");
  1425.   scanz ("%hd", &Awindow);
  1426. }
  1427.  
  1428. void
  1429. ChangeBetaWindow (void)
  1430. {
  1431.   ShowMessage ("Bwindow= ");
  1432.   scanz ("%hd", &Bwindow);
  1433. }
  1434.  
  1435. void
  1436. GiveHint (void)
  1437. {
  1438.   char s[40];
  1439.   algbr ((short) (hint >> 8), (short) (hint & 0xFF), false);
  1440.   strcpy (s, "try ");
  1441.   strcat (s, mvstr[0]);
  1442.   ShowMessage (s);
  1443. }
  1444.  
  1445. void
  1446. ChangeSearchDepth (void)
  1447. {
  1448.   ShowMessage ("depth= ");
  1449.   scanz ("%hd", &MaxSearchDepth);
  1450. }
  1451.  
  1452. void
  1453. SetContempt (void)
  1454. {
  1455.   ShowMessage ("contempt= ");
  1456.   scanz ("%hd", &contempt);
  1457. }
  1458.  
  1459. void
  1460. ChangeXwindow (void)
  1461. {
  1462.   ShowMessage ("xwndw= ");
  1463.   scanz ("%hd", &xwndw);
  1464. }
  1465.  
  1466. void
  1467. SelectLevel (void)
  1468. {
  1469.   ClrScreen ();
  1470.   gotoXY (32, 2);
  1471.   printz ("CHESS");
  1472.   gotoXY (20, 4);
  1473.   printz (" 1.   60 moves in   5 minutes");
  1474.   gotoXY (20, 5);
  1475.   printz (" 2.   60 moves in  15 minutes");
  1476.   gotoXY (20, 6);
  1477.   printz (" 3.   60 moves in  30 minutes");
  1478.   gotoXY (20, 7);
  1479.   printz (" 4.   40 moves in  30 minutes");
  1480.   gotoXY (20, 8);
  1481.   printz (" 5.   40 moves in  60 minutes");
  1482.   gotoXY (20, 9);
  1483.   printz (" 6.   40 moves in 120 minutes");
  1484.   gotoXY (20, 10);
  1485.   printz (" 7.   40 moves in 240 minutes");
  1486.   gotoXY (20, 11);
  1487.   printz (" 8.    1 move  in  15 minutes");
  1488.   gotoXY (20, 12);
  1489.   printz (" 9.    1 move  in  60 minutes");
  1490.   gotoXY (20, 13);
  1491.   printz ("10.    1 move  in 600 minutes");
  1492.  
  1493.   OperatorTime = 1;
  1494.   TCmoves = 60;
  1495.   TCminutes = 5;
  1496.  
  1497.   gotoXY (20, 17);
  1498.   printz ("Enter Level: ");
  1499. #ifndef __arm__
  1500.   refresh ();
  1501. #endif  
  1502.   scanz ("%ld", &Level);
  1503.   switch ((int) Level)
  1504.     {
  1505.     case 1:
  1506.       TCmoves = 60;
  1507.       TCminutes = 5;
  1508.       break;
  1509.     case 2:
  1510.       TCmoves = 60;
  1511.       TCminutes = 15;
  1512.       break;
  1513.     case 3:
  1514.       TCmoves = 60;
  1515.       TCminutes = 30;
  1516.       break;
  1517.     case 4:
  1518.       TCmoves = 40;
  1519.       TCminutes = 30;
  1520.       break;
  1521.     case 5:
  1522.       TCmoves = 40;
  1523.       TCminutes = 60;
  1524.       break;
  1525.     case 6:
  1526.       TCmoves = 40;
  1527.       TCminutes = 120;
  1528.       break;
  1529.     case 7:
  1530.       TCmoves = 40;
  1531.       TCminutes = 240;
  1532.       break;
  1533.     case 8:
  1534.       TCmoves = 1;
  1535.       TCminutes = 15;
  1536.       break;
  1537.     case 9:
  1538.       TCmoves = 1;
  1539.       TCminutes = 60;
  1540.       break;
  1541.     case 10:
  1542.       TCmoves = 1;
  1543.       TCminutes = 600;
  1544.       break;
  1545.     }
  1546.  
  1547.   TCflag = (TCmoves > 1);
  1548.   SetTimeControl ();
  1549.   ClrScreen ();
  1550.   UpdateDisplay (0, 0, 1, 0);
  1551. }
  1552.  
  1553. void
  1554. DoDebug (void)
  1555. {
  1556.   short c, p, sq, tp, tc, tsq, score;
  1557.   char s[40];
  1558.   
  1559.   ExaminePosition ();
  1560.   ShowMessage ("Enter piece: ");
  1561.   scanz ("%s", s);
  1562.   c = neutral;
  1563.   if (s[0] == 'w' || s[0] == 'W')
  1564.     c = white;
  1565.   if (s[0] == 'b' || s[0] == 'B')
  1566.     c = black;
  1567.   for(p = king; p > no_piece; p--)
  1568.     if ((s[1] == pxx[p]) || (s[1] == qxx[p]))
  1569.       break;
  1570.   for (sq = 0; sq < 64; sq++)
  1571.     {
  1572.       tp = board[sq];
  1573.       tc = color[sq];
  1574.       board[sq] = p;
  1575.       color[sq] = c;
  1576.       tsq = PieceList[c][1];
  1577.       PieceList[c][1] = sq;
  1578. #ifndef __arm__
  1579.       ShowPostnValue (sq);
  1580. #endif
  1581.       PieceList[c][1] = tsq;
  1582.       board[sq] = tp;
  1583.       color[sq] = tc;
  1584.     }
  1585.   ScorePosition (opponent, &score);
  1586.   ShowScore (score);
  1587. }
  1588.  
  1589. void
  1590. TestSpeed(void (*f) (short int side, short int ply))
  1591. {
  1592.   short i;
  1593.   long t1, t2;
  1594.  
  1595.   t1 = time (0);
  1596.   for (i = 0; i < 10000; i++)
  1597.     {
  1598.       f (opponent, 2);
  1599.     }
  1600.   t2 = time (0);
  1601.   NodeCnt = 10000L * (TrPnt[3] - TrPnt[2]);
  1602.   evrate = NodeCnt / (t2 - t1);
  1603.   ShowNodeCnt (NodeCnt, evrate);
  1604. }
  1605.  
  1606. void
  1607. InputCommand (void)
  1608.  
  1609. /*
  1610.   Process the users command. If easy mode is OFF (the computer is thinking
  1611.   on opponents time) and the program is out of book, then make the 'hint'
  1612.   move on the board and call SelectMove() to find a response. The user
  1613.   terminates the search by entering ^C (quit siqnal) before entering a
  1614.   command. If the opponent does not make the hint move, then set Sdepth to
  1615.   zero.
  1616. */
  1617.  
  1618. {
  1619.   short ok, tmp;
  1620.   unsigned short mv;
  1621.   char s[80];
  1622.  
  1623.   ok = flag.quit = false;
  1624.   player = opponent;
  1625.   ShowSidetomove ();
  1626.   ft = 0;
  1627.   if (hint > 0 && !flag.easy && Book == NULL)
  1628.     {
  1629.       fflush (stdout);
  1630.       time0 = time ((long *) 0);
  1631.       algbr ((short) hint >> 8, (short) hint & 0xFF, false);
  1632.       strcpy (s, mvstr[0]);
  1633.       tmp = epsquare;
  1634.       if (VerifyMove (s, 1, &mv))
  1635.         {
  1636.           ShowPrompt ();
  1637.           SelectMove (computer, 2);
  1638.           (void) VerifyMove (mvstr[0], 2, &mv);
  1639.           if (Sdepth > 0)
  1640.             Sdepth--;
  1641.         }
  1642.       ft = time ((long *) 0) - time0;
  1643.       epsquare = tmp;
  1644.     }
  1645.   signal (SIGINT, Die);
  1646. #ifndef MSDOS
  1647.   signal (SIGQUIT, Die);
  1648. #endif /* MSDOS */
  1649.   while (!(ok || flag.quit))
  1650.     {
  1651.       ShowPrompt ();
  1652.       scanz ("%s", s);
  1653.       player = opponent;
  1654.       ok = VerifyMove (s, 0, &mv);
  1655.       if (ok && mv != hint)
  1656.         {
  1657.           Sdepth = 0;
  1658.           ft = 0;
  1659.         }
  1660.       if (*s == '\0')
  1661.         UpdateDisplay (0, 0, 1, 0);
  1662.       if (strcmp (s, "bd") == 0)
  1663.         {
  1664.           ClrScreen ();
  1665.           UpdateDisplay (0, 0, 1, 0);
  1666.         }
  1667.       if ((strcmp (s, "quit") == 0) || (strcmp (s, "exit") == 0))
  1668.         flag.quit = true;
  1669.       if (strcmp (s, "post") == 0)
  1670.         flag.post = !flag.post;
  1671.       if (strcmp (s, "edit") == 0)
  1672.         EditBoard ();
  1673.       if (strcmp (s, "go") == 0)
  1674.         ok = true;
  1675.       if (strcmp (s, "help") == 0)
  1676.         help ();
  1677.       if (strcmp (s, "force") == 0)
  1678.         flag.force = !flag.force;
  1679.       if (strcmp (s, "book") == 0)
  1680.         Book = NULL;
  1681.       if (strcmp (s, "undo") == 0 && GameCnt > 0)
  1682.         Undo ();
  1683.       if (strcmp (s, "new") == 0){
  1684.           NewGame ();
  1685.           ClrScreen ();
  1686.           UpdateDisplay (0, 0, 1, 0);
  1687.         }
  1688.       if (strcmp (s, "list") == 0)
  1689.         ListGame ();
  1690.       if (strcmp (s, "level") == 0)
  1691.         SelectLevel ();
  1692.       if (strcmp (s, "hash") == 0)
  1693.         flag.hash = !flag.hash;
  1694.       if (strcmp (s, "beep") == 0)
  1695.         flag.beep = !flag.beep;
  1696.       if (strcmp (s, "Awindow") == 0)
  1697.         ChangeAlphaWindow ();
  1698.       if (strcmp (s, "Bwindow") == 0)
  1699.         ChangeBetaWindow ();
  1700.       if (strcmp (s, "hint") == 0)
  1701.         GiveHint ();
  1702.       if (strcmp (s, "both") == 0)
  1703.         {
  1704.           flag.bothsides = !flag.bothsides;
  1705.           Sdepth = 0;
  1706.           SelectMove (opponent, 1);
  1707.           ok = true;
  1708.         }
  1709.       if (strcmp (s, "reverse") == 0)
  1710.         {
  1711.           flag.reverse = !flag.reverse;
  1712.           ClrScreen ();
  1713.           UpdateDisplay (0, 0, 1, 0);
  1714.         }
  1715. #if !defined(MSDOS) || defined(SEVENBIT)
  1716.       if (strcmp (s, "shade") == 0)
  1717.         {
  1718.           shade = !shade;
  1719.           ClrScreen ();
  1720.           UpdateDisplay (0, 0, 1, 0);
  1721.         }
  1722. #endif /* MSDOS && !SEVENBIT */
  1723.       if (strcmp (s, "switch") == 0)
  1724.         {
  1725.           computer = otherside[computer];
  1726.           opponent = otherside[opponent];
  1727.           flag.force = false;
  1728.           Sdepth = 0;
  1729.           ok = true;
  1730.         }
  1731.       if (strcmp (s, "white") == 0)
  1732.         {
  1733.           computer = white;
  1734.           opponent = black;
  1735.           ok = true;
  1736.           flag.force = false;
  1737.           Sdepth = 0;
  1738.         }
  1739.       if (strcmp (s, "black") == 0)
  1740.         {
  1741.           computer = black;
  1742.           opponent = white;
  1743.           ok = true;
  1744.           flag.force = false;
  1745.           Sdepth = 0;
  1746.         }
  1747.       if (strcmp (s, "remove") == 0 && GameCnt > 1)
  1748.         {
  1749.           Undo ();
  1750.           Undo ();
  1751.         }
  1752.       if (strcmp (s, "get") == 0)
  1753.         GetGame ();
  1754.       if (strcmp (s, "save") == 0)
  1755.         SaveGame ();
  1756.       if (strcmp (s, "depth") == 0)
  1757.         ChangeSearchDepth ();
  1758.       if (strcmp (s, "random") == 0)
  1759.         dither = 6;
  1760.       if (strcmp (s, "easy") == 0)
  1761.         flag.easy = !flag.easy;
  1762.       if (strcmp (s, "contempt") == 0)
  1763.         SetContempt ();
  1764.       if (strcmp (s, "xwndw") == 0)
  1765.         ChangeXwindow ();
  1766.       if (strcmp (s, "coords") == 0)
  1767.         {
  1768.           coords = !coords;
  1769.           UpdateDisplay (0, 0, 1, 0);
  1770.         }
  1771. #if !defined(MSDOS) || defined(SEVENBIT)
  1772.       if (strcmp (s, "stars") == 0)
  1773.         {
  1774.           stars = !stars;
  1775.           UpdateDisplay (0, 0, 1, 0);
  1776.         }
  1777. #endif /* MSDOS && !SEVENBIT */
  1778.       if (strcmp (s, "test") == 0)
  1779.         {
  1780.           ShowMessage("Testing MoveList Speed");
  1781.           TestSpeed (MoveList);
  1782.           ShowMessage("Testing CaptureList Speed");
  1783.           TestSpeed (CaptureList);
  1784.         }
  1785.       if (strcmp (s, "p") == 0)
  1786.         ShowPostnValues ();
  1787.       if (strcmp (s, "debug") == 0)
  1788.         DoDebug ();
  1789.       if (strcmp (s, "rv") == 0)
  1790.         {
  1791.           rv = !rv;
  1792. #if !defined(MSDOS) || defined(SEVENBIT)
  1793.           shade = !rv;
  1794.           stars = !rv;
  1795. #endif /* MSDOS && !SEVENBIT */
  1796.           UpdateDisplay (0, 0, 1, 0);
  1797.         }
  1798.     }
  1799.  
  1800.   ClearMessage ();
  1801.   ElapsedTime (1);
  1802.   if (flag.force)
  1803.     {
  1804.       computer = opponent;
  1805.       opponent = otherside[computer];
  1806.     }
  1807.   signal (SIGINT, TerminateSearch);
  1808. #ifndef MSDOS
  1809.   signal (SIGQUIT, TerminateSearch);
  1810. #endif /* MSDOS */
  1811. }
  1812.  
  1813.  
  1814. #ifdef __arm__
  1815.  
  1816. initscr()
  1817. {
  1818.  putchar(12);
  1819.  putchar(4);
  1820.  standend();
  1821. }
  1822.  
  1823. clear()
  1824. {
  1825.  putchar(12);
  1826.  putchar(4);
  1827. }
  1828.  
  1829. clrtoeol()
  1830. {
  1831.  int i;
  1832.    
  1833.  putchar(27);
  1834. }
  1835.  
  1836. standout()
  1837. {
  1838.  putchar(17);
  1839.  putchar(8);
  1840.  putchar(17);
  1841.  putchar(129);
  1842. }
  1843.  
  1844. standend()
  1845. {
  1846.  putchar(17);
  1847.  putchar(15);
  1848.  putchar(17);
  1849.  putchar(128);
  1850. }
  1851.  
  1852.  
  1853. #endif
  1854.  
  1855.